using Microsoft.Practices.ObjectBuilder2;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.ObjectBuilder;

namespace Sessionizer.Core.Unity
{
    public sealed class SessionLifetimeExtension : UnityContainerExtension
    {
        private static void Register(IUnityContainer container)
        {
            container.RegisterType<ISessionFactory, SessionFactory>();
            container.RegisterType<ISessionStorage, SessionStorage>();
            container.RegisterType<ISessionConfigurationBuilder, SessionConfigurationBuilder>();
            container.RegisterType<ISession, Session>(new SessionGuardLifetimeManager());
            container.RegisterType<SessionLifetimeManager>();
            container.RegisterType(typeof (ISessionsFactory<>), typeof (SessionsFactory<>));
            container.RegisterType(typeof (ISessions<>), typeof (Sessions<>), new SessionLifetimeManager());
        }

        protected override void Initialize()
        {
            Context.Strategies.Add(new SetKeyBuilderStrategy(), UnityBuildStage.Lifetime);
            Register(Container);
        }

        public override void Remove()
        {
        }

        private class SetKeyBuilderStrategy : BuilderStrategy
        {
            public override void PreBuildUp(IBuilderContext context)
            {
                var lifetimePolicy = context.PersistentPolicies.Get<ILifetimePolicy>(context.BuildKey);
                var lifetimeManager = lifetimePolicy as SessionLifetimeManager;
                if (!ReferenceEquals(lifetimeManager, null))
                {
                    lifetimeManager.SetBuildKey(context.BuildKey);
                }
            }
        }
    }
}